using System;
using System.Collections;
using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Dimok.Web.UI {

	[AspNetHostingPermission(SecurityAction.Demand,
			Level = AspNetHostingPermissionLevel.Minimal)]
	[AspNetHostingPermission(SecurityAction.InheritanceDemand,
			Level = AspNetHostingPermissionLevel.Minimal)]
	public class DataBoundText : DataBoundControl {

		private string text;
		[Bindable(true)]
		public string Text { get { return text; } set { text = value; } }
		public string FormatString = null;
		private IList alBoxSet;
		public IList BoxSet {
			get {
				if (null == alBoxSet) {
					alBoxSet = new ArrayList();
				}
				return alBoxSet;
			}
		}
		public string DataTextField {
			get {
				object o = ViewState["DataTextField"];
				return ((o == null) ? string.Empty : (string)o);
			}
			set {
				ViewState["DataTextField"] = value;
				if (Initialized) {
					OnDataPropertyChanged();
				}
			}
		}
		protected override void PerformSelect() {

			// Call OnDataBinding here if bound to a data source using the
			// DataSource property (instead of a DataSourceID), because the
			// databinding statement is evaluated before the call to GetData.       
			if (!IsBoundUsingDataSourceID) {
				OnDataBinding(EventArgs.Empty);
			}

			// The GetData method retrieves the DataSourceView object from  
			// the IDataSource associated with the data-bound control.            
			GetData().Select(CreateDataSourceSelectArguments(),
					OnDataSourceViewSelectCallback);

			// The PerformDataBinding method has completed.
			RequiresDataBinding = false;
			MarkAsDataBound();

			// Raise the DataBound event.
			OnDataBound(EventArgs.Empty);
		}
		private void OnDataSourceViewSelectCallback(IEnumerable retrievedData) {

			// Call OnDataBinding only if it has not already been 
			// called in the PerformSelect method.
			if (IsBoundUsingDataSourceID) {
				OnDataBinding(EventArgs.Empty);
			}
			// The PerformDataBinding method binds the data in the  
			// retrievedData collection to elements of the data-bound control.
			PerformDataBinding(retrievedData);
		}
		protected override void PerformDataBinding(IEnumerable retrievedData) {
			base.PerformDataBinding(retrievedData);

			// If the data is retrieved from an IDataSource as an 
			// IEnumerable collection, attempt to bind its values to a 
			// set of TextBox controls.
			if (retrievedData != null) {

				foreach (object dataItem in retrievedData) {

					// The dataItem is not just a string, but potentially
					// a System.Data.DataRowView or some other container. 
					// If DataTextField is set, use it to determine which 
					// field to render. Otherwise, use the first field.                    
					if (DataTextField.Length > 0) {
						text = DataBinder.GetPropertyValue(dataItem, DataTextField, FormatString);
					} else {
						PropertyDescriptorCollection props =
								TypeDescriptor.GetProperties(dataItem);

						// Set the "default" value of the TextBox.
						text = String.Empty;

						// Set the true data-bound value of the TextBox,
						// if possible.
						if (props.Count >= 1) {
							if (null != props[0].GetValue(dataItem)) {
								text = props[0].GetValue(dataItem).ToString();
							}
						}
					}
					break;
				}
			} else text = string.Empty;
		}
		protected override void Render(HtmlTextWriter writer) {

			// Render nothing if the control is empty.            
			if (text == string.Empty) {
				return;
			}

			// Make sure the control is declared in a form tag 
			// with runat=server.
			if (Page != null) {
				Page.VerifyRenderingInServerForm(this);
			}
			writer.Write(text);
			return;
			// For this example, render the BoxSet as 
			// an unordered list of TextBox controls.            
			writer.RenderBeginTag(HtmlTextWriterTag.Ul);

			foreach (object item in BoxSet) {

				TextBox box = (TextBox)item;

				// Write each element as 
				// <li><input type="text" value="string"><input/></li>

				writer.WriteBeginTag("li");
				writer.Write(">");
				writer.WriteBeginTag("input");
				writer.WriteAttribute("type", "text");
				writer.WriteAttribute("value", box.Text);
				writer.Write(">");
				writer.WriteEndTag("input");
				writer.WriteEndTag("li");
			}

			writer.RenderEndTag();
		}
	}
}
